package LoginManager;

import LoginManager.ImagePreProcess2;
import Utils.RegexUtils;
import org.apache.http.*;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.apache.commons.io.FileUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

public class Login {
    String userName = "";
    String passWord = "";
    String rootUrl = "http://jwgl.fafu.edu.cn";
    static String saveCodeDir = "C:\\Users\\Administrator\\Desktop\\CodeTest\\";
    static String codeImgName = "CODE.gif";
    String webSession = null;
    String interpretUrl = "";
    LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
    CloseableHttpClient httpClient = HttpClients.custom().setRedirectStrategy(redirectStrategy).build();
    HttpClientContext  context = HttpClientContext.create();
    HttpGet httpGet = null;
    int count = 0;
    boolean isSuccess = false;

    public Login(){
        boolean isSuccess = false;
    }

    public boolean getStatus(){
        return isSuccess;
    }

    public Login(String userName,String passWord){
        this.userName = userName;
        this.passWord = passWord;
    }
    //处理重定向,获取图片imgUrl 资源路径
    public String handleRedirect(String url){
        httpGet = new HttpGet(url);
        try{
            CloseableHttpResponse response = httpClient.execute(httpGet,context);
            System.out.println(response.getStatusLine().getStatusCode());
            HttpHost target = context.getTargetHost();
            List<URI> redirectLocations = context.getRedirectLocations();
            URI location = URIUtils.resolve(httpGet.getURI(), target, redirectLocations);
            interpretUrl = location.toASCIIString();
            String imgDir = interpretUrl.replace("default2.aspx","");
            System.out.println(imgDir +".................");
            return imgDir;
        }catch (Exception e){
            e.printStackTrace();
        }
        return "";
    }


    //获取验证码图片
    public BufferedImage handlerTheCode(String imgDir) throws Exception{
        //根据重定向地址解析图片//CheckCode.aspx
        HttpGet PicturehttpGet = new HttpGet(imgDir + "CheckCode.aspx");
        while(true){
            CloseableHttpResponse pictureResponse = httpClient.execute(PicturehttpGet);
            if(pictureResponse.getStatusLine().getStatusCode() == 200){
                HttpEntity pictureEntity = pictureResponse.getEntity();
                InputStream inputStream = pictureEntity.getContent();
                // 使用 common-io 下载图片到本地，注意图片名不能重复 ✔
                FileUtils.copyToFile(inputStream, new File(saveCodeDir + codeImgName));
                BufferedImage bi = ImageIO.read(inputStream);
                httpClient.close();
                return bi;
            }
        }
    }

    String returnMessage = "";
    public String loginStimulate() {
        try{
            //获取重定向地址
            String imgDir = handleRedirect(rootUrl);
            //获取验证码图片
            BufferedImage bufferedImage =  handlerTheCode(imgDir);
            //识别验证码,
            String code = ImagePreProcess2.getCodeString(saveCodeDir+codeImgName);

            //填写表单数据
            List<NameValuePair> form = new ArrayList<>();
            form.add(new BasicNameValuePair("__VIEWSTATE", "dDwtNTE2MjI4MTQ7Oz7ofhHy/vlg6BtgZpsohZPJJUFItA=="));
            form.add(new BasicNameValuePair("__VIEWSTATEGENERATOR", "92719903"));
            form.add(new BasicNameValuePair("txtUserName",userName));
            form.add(new BasicNameValuePair("Textbox1", ""));
            form.add(new BasicNameValuePair("TextBox2", passWord));
            form.add(new BasicNameValuePair("txtSecretCode", code));
            form.add(new BasicNameValuePair("Button1", ""));
            form.add(new BasicNameValuePair("lbLanguage", ""));
            form.add(new BasicNameValuePair("hidPdrs", ""));
            form.add(new BasicNameValuePair("hidsc", ""));

            //模拟登录
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(form);
            HttpPost httpPost = new HttpPost(interpretUrl);
            httpPost.setEntity(entity);
            httpClient = HttpClients.createDefault();
            HttpResponse response = httpClient.execute(httpPost);

            //获取登录结果
            int status = response.getStatusLine().getStatusCode();
            HttpEntity responseEntity = response.getEntity();
            Document doc = Jsoup.parse(EntityUtils.toString(responseEntity));
            System.out.println("STATUS:" + status);
            if (status == 302) {
                Elements element = doc.getElementsByTag("a");
                //登录成功
                String url = element.get(0).attr("href");
                System.out.println(url);
                isSuccess = true;
                return rootUrl+"/"+url;
            } else if(status < 400){
                //获取错误提示
                String warnStr = doc.getElementsByTag("script").html();
                if(warnStr.length() != 0 ){
                    //使用正则提取
                    warnStr = RegexUtils.findSingleStr(warnStr,"alert\\('(.*)'\\);",1);
                    if(warnStr.indexOf("验证码") != -1){//如果是验证码错误则重试验证码
                        System.out.println("-------验证码错误,重试中----------" + code);
                        return loginStimulate();
                    }else{//提示 账号密码错误
                        System.out.println("--WARN:--"+warnStr);
                        return warnStr;
                    }
                }
            }else{
                return loginStimulate();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

}
